package com.nuanshui.heatedloan.credit.service;

import com.nuanshui.framework.consts.TransactionManagerType;
import com.nuanshui.framework.lang.DateUtil;
import com.nuanshui.heatedloan.constant.ServiceConstant;
import com.nuanshui.heatedloan.credit.constant.*;
import com.nuanshui.heatedloan.credit.dal.mapper.PayOrderInfoMapper;
import com.nuanshui.heatedloan.credit.facade.CustomerCreditResultService;
import com.nuanshui.heatedloan.credit.facade.CustomerProduceService;
import com.nuanshui.heatedloan.credit.facade.PayOrderInfoService;
import com.nuanshui.heatedloan.credit.facade.third.party.RiskManagerInteractionService;
import com.nuanshui.heatedloan.credit.form.PayOrderInfoForm;
import com.nuanshui.heatedloan.credit.request.RiskSelectRequest;
import com.nuanshui.heatedloan.credit.response.RiskSelectResponse;
import com.nuanshui.heatedloan.credit.utils.CalculateLoanAmt;
import com.nuanshui.heatedloan.credit.vo.PayOrderInfoVO;
import com.nuanshui.heatedloan.pageable.Pager;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by wangxw on 2017/6/26.
 */
@Service(ServiceConstant.PAYORDERINFOSERVICE)
@Transactional(readOnly=true,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
public class PayOrderInfoServiceImpl implements PayOrderInfoService {

    private Logger logger= LoggerFactory.getLogger(PayOrderInfoServiceImpl.class);

    @Autowired
    private PayOrderInfoMapper payOrderInfoMapper;


    @Autowired
    private CustomerCreditResultService customerCreditResultService;

    @Autowired
    private CustomerProduceService customerProduceService;

    @Autowired
    private RiskManagerInteractionService riskManagerInteractionService;

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void savePayOrderInfo(PayOrderInfoForm payOrderInfoForm) {
        payOrderInfoMapper.savePayOrderInfo(payOrderInfoForm);
    }

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void updatePayOrderInfo(PayOrderInfoForm payOrderInfoForm) {
        payOrderInfoMapper.updatePayOrderInfo(payOrderInfoForm);
    }

    @Override
    public PayOrderInfoVO loadVO(PayOrderInfoForm payOrderInfoForm) {

        PayOrderInfoVO payOrderInfoVO=payOrderInfoMapper.loadVO(payOrderInfoForm);

        this.dealPayOrderInfoVO(payOrderInfoVO);
        return payOrderInfoVO;
    }

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void updateOrderStatusByOrderno(String orderNo,String orderStatus) {
        payOrderInfoMapper.updateOrderStatusByOrderno(orderNo,orderStatus);
    }

    @Override
    public List<PayOrderInfoVO> loadPayOrderInfoVOByUserId(Pager<PayOrderInfoVO> pager,String userId) {
        List<PayOrderInfoVO> list =payOrderInfoMapper.loadPayOrderInfoVOByUserId(pager,userId);
        return this.dealRemainOrOverdueDays(list);
    }

    @Override
    public List<PayOrderInfoVO> loadPayOrderInfoVOByUserId(String userId) {
        List<PayOrderInfoVO> list =payOrderInfoMapper.loadPayOrderInfoVOByUserId(userId);
        return this.dealRemainOrOverdueDays(list);
    }

    /**
     *处理用户逾期天数或者剩余天数
     * @return
     */
    private List<PayOrderInfoVO> dealRemainOrOverdueDays(List<PayOrderInfoVO> list){
        for(PayOrderInfoVO vo : list){
            this.dealPayOrderInfoVO(vo);
            switch (vo.getOrderStatus()){
                case OrderType.NOREIMBURSEMENT :  //未逾期待还款
                    int remainDay= vo.getLoadDays()-DateUtil.dateNum(vo.getLendTime(), Calendar.getInstance().getTime());
                    vo.setRemainDay(remainDay);
                    logger.info("----------剩余天数:"+vo.getRemainDay());
                    continue;
                case OrderType.OVERDUEPAYMENT :  //未逾期待还款
                    int overdueDay= vo.getLoadDays()-DateUtil.dateNum(vo.getLendTime(), Calendar.getInstance().getTime());
                    vo.setOverdueDays(overdueDay);
                    logger.info("----------逾期天数:"+vo.getRemainDay());
                    continue;
                default:
                    break;
            }
        }
        return list;
    }

    @Override
    public List<PayOrderInfoVO> loadValidPayOrderInfoVOByUserId(String userId) {
        List<PayOrderInfoVO>  list =payOrderInfoMapper.loadPayOrderInfoVOByUserIdAndOrderStatus(userId);
        for(PayOrderInfoVO vo : list){
            this.dealPayOrderInfoVO(vo);
            //剩余天数只针对未逾期情况
           if(vo.getLendTime()!=null && vo.getShouldReturnTime() != null && vo.getOverdueDays() <= 0){
               int remainDay= (int)DateUtil.getIntervalDay(Calendar.getInstance().getTime(),vo.getShouldReturnTime());
               vo.setRemainDay(remainDay);
           }
           vo.setPayAmount(vo.getLoanAmount()+vo.getBaseAmt()+vo.getInterestAmt()+vo.getOverdueFee());
        }
        sortIntMethod(list);
        return list;
    }

    /**
     * 订单排序
     * @param list
     */
    private  void sortIntMethod(List list) {
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                PayOrderInfoVO vo1 = (PayOrderInfoVO) o1;
                PayOrderInfoVO vo2 = (PayOrderInfoVO) o2;
                if(vo1.getOverdueDays()>0 ||vo2.getOverdueDays()>0){
                    return 0;
                }
                if (vo1.getRemainDay() > vo2.getRemainDay()) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
    }

    @Override
    public List<PayOrderInfoVO> loadNoSingleLoanOrderByUserId(String userId){
        return payOrderInfoMapper.loadNoSingleLoanOrderByUserId(userId);
    }

    @Override
    public List<PayOrderInfoVO> loadSingleLoanBeforeReturn(@Param("userId") String userId) {
        return payOrderInfoMapper.loadSingleLoanBeforeReturn(userId);
    }

    @Override
    public List<PayOrderInfoVO> loadSingleLoanNoPay(String userId, int borrowType){
       return payOrderInfoMapper.loadSingleLoanNoPay(userId,borrowType);
    }

    @Override
    public PayOrderInfoVO loadVOById(String id) {
        return payOrderInfoMapper.loadVOById(id);
    }

    @Override
    public float loadUserLoanAmount(String userId) {
        return payOrderInfoMapper.loadUserLoanAmount(userId);
    }

    @Override
    public int loadUserLoanAccount(String userId) {
        return payOrderInfoMapper.loadUserLoanAccount(userId);
    }

    @Override
    public List<PayOrderInfoVO> loadVOByStatusAndType(String userId, List<Integer> statuss, List<Integer> types) {
        return payOrderInfoMapper.loadVOByStatusAndType(userId,statuss,types);
    }

    @Override
    public Integer getSumAmtByUserIdByTypeByStatus(String userId, List<Integer> statuss, List<Integer> types) {
        return payOrderInfoMapper.getSumAmtByUserIdByTypeByStatus(userId,statuss,types);
    }

    @Override
    public List<PayOrderInfoVO> loadPayOrderInfoVOByUserIdAndBorrowType(String userId, Integer borrowType) {
        return payOrderInfoMapper.loadPayOrderInfoVOByUserIdAndBorrowType(userId,borrowType);
    }

    @Override
    public Integer loadSumByUserId(String userId) {
        return payOrderInfoMapper.loadSumByUserId(userId);
    }

    @Override
    public PayOrderInfoVO loadVOByOrderNo(String orderNo) {

        PayOrderInfoVO vo=payOrderInfoMapper.loadVOByOrderNo(orderNo);
        this.dealPayOrderInfoVO(vo);
        return vo;
    }

    /**
     * 处理订单上的费用信息
     * @param vo
     * @return
     */
    private void dealPayOrderInfoVO( PayOrderInfoVO vo){
        if(vo != null){
            switch (vo.getBorrowType()){
                case BorrowType.SINGLELOAN:
                    CalculateLoanAmtResponse responseSingleLoan =CalculateLoanAmt.calculateLoanSingleAmt(vo.getBaseRate(),vo.getInterestRate(),vo.getLoanAmount(),vo.getLoadDays());
                    vo.setBaseAmt(responseSingleLoan.getBaseAmt());
                    vo.setInterestAmt(responseSingleLoan.getInterestAmt());
                    break;
                case BorrowType.LIGHTLOAN :
                    CalculateLoanAmtResponse responseLoanLinght= CalculateLoanAmt.calculateLoanLightAmt(vo.getBaseRate(),vo.getInterestRate(),vo.getLoanAmount(),vo.getLoadDays());
                    vo.setBaseAmt(responseLoanLinght.getBaseAmt());
                    vo.setInterestAmt(responseLoanLinght.getInterestAmt());
                    break;
                default:
                    break;
            }
            vo.setPayAmount(vo.getLoanAmount()+vo.getBaseAmt()+vo.getInterestAmt()+vo.getOverdueFee());
        }
    }

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER,propagation = Propagation.REQUIRES_NEW)
    public void updateOrderApprovedStatusByUserIdAndOrderNo(String userId,String orderNo,int status){
        payOrderInfoMapper.updateOrderStatusByUserIdAndOrderNo(userId,orderNo,status);
    }

    @Override
    public void updateOrderLendStatusByUserIdAndOrderNo(String userId, String orderNo, int status, Date date) {
        payOrderInfoMapper.updateOrderLendStatusByUserIdAndOrderNo(userId,orderNo,status,date);
    }

    @Override
    public Integer getLoanCountByType(String userId, String borrowType, List<Integer> statuss) {
        return payOrderInfoMapper.getLoanCountByType(userId,borrowType,statuss);
    }

    @Override
    public List<PayOrderInfoVO> loadVOByUserIdByTypeByStatus(String userId, List<Integer> statuss, List<Integer> types) {
        return payOrderInfoMapper.loadVOByUserIdByTypeByStatus(userId,statuss,types);
    }

    @Override
    public List<PayOrderInfoVO> loadVoAuditByUserId(String userId, Integer borrowType) {
        return payOrderInfoMapper.loadVoAuditByUserId(userId,borrowType);
    }

    @Override
    public int  loadUserLoanAccountByStatusAndType(String userId,List<Integer> statuss, List<Integer> types){
        return payOrderInfoMapper.loadUserLoanAccountByStatusAndType(userId,statuss,types);
    }

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void updateLateInfoByOrderNo(String orderNo,int overdueFee,int overdueDays,int orderStatus){
        payOrderInfoMapper.updateLateInfoByOrderNo(orderNo,overdueFee,overdueDays,orderStatus);
    }

    @Override
    public String isnewOldSigns(String userId){
        String status= NewOldSignsType.NEWUSER;
        List<PayOrderInfoVO> payOrderInfoVOs=new ArrayList<PayOrderInfoVO>();
        payOrderInfoVOs=this.loadPayOrderInfoVOByUserId(userId);
        if(payOrderInfoVOs.size()==0){
            return status;
        }
        for(PayOrderInfoVO payOrderInfoVO:payOrderInfoVOs){
            if(payOrderInfoVO.getOrderStatus()>OrderType.AUDITFAILED
                    &&payOrderInfoVO.getOrderStatus()!=OrderType.LENDFAIL
                    &&payOrderInfoVO.getOrderStatus()!=OrderType.APPROVEDORDER){
                status=NewOldSignsType.OLDUSER;
                return status;
            }
        }
        return NewOldSignsType.LESSNEWUSER;
    }

    public RiskSelectResponse dealRiskSelect(RiskSelectRequest riskSelectRequest){
        RiskSelectResponse riskSelectResponse=new RiskSelectResponse();
        if(RiskSelectType.OVERDUEDAY.equals(riskSelectRequest.getType())){
            riskSelectResponse=this.getOverdueDay(riskSelectRequest);
        }else if(RiskSelectType.ISOVERDUE.equals(riskSelectRequest.getType())){
            riskSelectResponse=this.isOverdue(riskSelectRequest);
        }
        return riskSelectResponse;
    }

    private RiskSelectResponse getOverdueDay(RiskSelectRequest riskSelectRequest){
        logger.info("=====查询的数据类型为===="+riskSelectRequest.getType()+"======");
        logger.info("=====查询的数据手机号为===="+riskSelectRequest.getPhone()+"======");
        RiskSelectResponse riskSelectResponse=new RiskSelectResponse();
       PayOrderInfoVO payOrderInfoVO=this.
               getOverdueDay(riskSelectRequest.getPhone(),riskSelectRequest.getUserId());
       if(payOrderInfoVO==null){
           riskSelectResponse.setOverdueDay("0");
       }else{
           riskSelectResponse.setOverdueDay(payOrderInfoVO.getOverdueDays()+"");
       }
        logger.info("=============查询数据完成============");
        riskManagerInteractionService.selectOverdueInfo(riskSelectRequest,riskSelectResponse);
        return riskSelectResponse;
    }

    private RiskSelectResponse isOverdue(RiskSelectRequest riskSelectRequest){
        RiskSelectResponse riskSelectResponse=new RiskSelectResponse();
        List<PayOrderInfoVO> payOrderInfoVOs=this.isOverdue(riskSelectRequest.getPhone());
        if(payOrderInfoVOs!=null&&payOrderInfoVOs.size()>0){
            riskSelectResponse.setIsOverdue("1");  //逾期
            List<String> lists=new ArrayList<String>();
            for(PayOrderInfoVO payOrderInfoVO:payOrderInfoVOs){
                lists.add(payOrderInfoVO.getOrderNo());
            }
            riskSelectResponse.setOverdueOrderId(lists);
        }else{
            riskSelectResponse.setIsOverdue("0");   //沒有逾期
        }
        return riskSelectResponse;
    }

    @Override
    public PayOrderInfoVO getOverdueDay(String phone, String userId) {
        List<PayOrderInfoVO> payOrderInfoVOs=payOrderInfoMapper.getOverdueDay(phone,userId);
        if(payOrderInfoVOs.size()>0){
         return payOrderInfoVOs.get(0);
        }
        return null;
    }

    @Override
    public List<PayOrderInfoVO> isOverdue(String phone) {
        List<PayOrderInfoVO> payOrderInfoVOs =payOrderInfoMapper.isOverdue(phone);
        return payOrderInfoVOs;
    }

    @Override
    @Transactional(readOnly=false,value= TransactionManagerType.CREDIT_TRANSACTION_MANAGER)
    public void updateStatusAndTime(int updateType,int status,String orderNo,String repayMixCardNo){
        PayOrderInfoVO payOrderInfoVO=payOrderInfoMapper.loadVOByOrderNo(orderNo);
        int loanDay=payOrderInfoVO.getLoadDays();
        Date shouldReturnTime=DateUtil.addDays(new Date(),loanDay);
        shouldReturnTime=DateUtil.getDateHourMinuteSecond(shouldReturnTime,23,58,58);
        payOrderInfoMapper.updateStatusAndTime(updateType,status,orderNo,shouldReturnTime,repayMixCardNo);
    }


    @Override
    public List<PayOrderInfoVO> loadVoRepayByUserId(String userId) {
        return payOrderInfoMapper.loadVoRepayByUserId(userId);
    }

    public static void main(String[] args) {
        Date shouldReturnTime=DateUtil.addDays(new Date(),3);
        shouldReturnTime=DateUtil.getDateHourMinuteSecond(shouldReturnTime,23,59,58);
        System.out.println(shouldReturnTime);
    }

}
